package com.kun.companion.core.util;

import com.kun.companion.core.AbstractApplication;
import com.kun.companion.core.exception.BizException;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 加载resources目录下的资源
 *
 * @author gzc
 * @since 2025/2/24
 **/
public class ResourceLoader {
    /**
     * 加载器
     */
    public static final Class<? extends AbstractApplication> LOADER = AbstractApplication.getLoader();

    /**
     * 读取资源文件为字符串（通过类路径）
     *
     * @param fileName 资源路径，从classpath根目录开始（如："config/app.conf"）
     */
    public static String readResourceFile(String fileName) {
        try (InputStream inputStream = AbstractApplication.getLoader().getResourceAsStream(fileName)) {
            if (inputStream == null) {
                throw new BizException("文件未找到: " + fileName);
            }
            return new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
        } catch (IOException e) {
            throw new BizException("读取文件失败", e);
        }
    }

    /**
     * 读取资源文件为字符串（通过指定类）
     *
     * @param fileName  相对于类的路径（如："app.conf"）
     * @param mainClass 用于定位资源的类
     */
    public static String readResourceFile(String fileName, Class<?> mainClass) {
        try (InputStream inputStream = mainClass.getResourceAsStream(fileName)) {
            if (inputStream == null) {
                throw new BizException("文件未找到: " + fileName);
            }
            return new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
        } catch (IOException e) {
            throw new BizException("读取文件失败", e);
        }
    }

    /**
     * 读取资源文件为字节数组（适用于二进制文件）
     *
     * @param fileName 资源路径
     */
    public static byte[] readResourceAsBytes(String fileName) {
        try (InputStream inputStream = AbstractApplication.getLoader().getResourceAsStream(fileName)) {
            if (inputStream == null) {
                throw new BizException("文件未找到: " + fileName);
            }
            return inputStream.readAllBytes();
        } catch (IOException e) {
            throw new BizException("读取文件失败", e);
        }
    }

    /**
     * 检查资源文件是否存在
     *
     * @param fileName 资源路径
     * @return 存在返回true
     */
    public static boolean resourceExists(String fileName) {
        try (InputStream ignored = AbstractApplication.getLoader().getResourceAsStream(fileName)) {
            return ignored != null;
        } catch (IOException e) {
            return false;
        }
    }

    /**
     * 获取资源文件的绝对路径URL
     *
     * @param fileName 资源路径
     * @return 资源的URL对象
     */
    public static URL getResourceUrl(String fileName) {
        URL url = AbstractApplication.class.getResource(fileName);
        if (url == null) {
            throw new BizException("资源路径不存在: " + fileName);
        }
        return url;
    }

    /**
     * 列出目录下的资源文件（仅限JAR包外目录有效）
     *
     * @param dirPath 目录路径（如："config/"）
     * @return 文件名列表（无目录结构）
     */
    public static List<String> listResourceFiles(String dirPath) {
        try {
            URL url = LOADER.getResource(dirPath);
            if (url == null) {
                return Collections.emptyList();
            }

            List<String> fileNames = new ArrayList<>();
            try (java.io.BufferedReader reader = new java.io.BufferedReader(
                    new java.io.InputStreamReader(url.openStream(), StandardCharsets.UTF_8))) {
                String line;
                while ((line = reader.readLine()) != null) {
                    fileNames.add(line);
                }
            }
            return fileNames;
        } catch (IOException e) {
            throw new BizException("无法列出资源目录: " + dirPath, e);
        }
    }

    private static ClassLoader getClassLoader() {
        return Thread.currentThread().getContextClassLoader();
    }

    /**
     * 读取多文件合并内容（适用于分片配置）
     *
     * @param filePattern 文件名模式（如："messages_*.txt"）
     */
    public static String readCombinedFiles(String filePattern) {
        // 实现需要依赖特定库，此处仅展示接口设计
        throw new UnsupportedOperationException("需要实现文件模式匹配逻辑");
    }

}
